package wsz.code.service.impl;

import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.util.CollectionUtils;
import wsz.api.CodeService;
import wsz.api.EmailService;
import wsz.api.UserService;
import wsz.code.dao.AuthCodeDao;
import wsz.pojo.AuthCode;
import wsz.util.CommonUtils;
import wsz.util.ConstantsUtils;

import java.sql.Timestamp;
import java.util.List;

/**
 * 邮件验证码
 * @author wsz
 * @date 2021/12/27 11:29
 **/
@Service
public class AuthCodeServiceImpl implements CodeService {

    @Reference(check = false, timeout = 5000)
    private EmailService emailService;

    @Autowired
    private AuthCodeDao codeEmailDao;
    // 超时时间
    private int CODE_TIME_OUT = 1000 * 60 * 10;

    /**
     * 生成验证码并发送邮箱
     * @param email
     * @return
     */
    @Override
    public boolean create(String email) {
        // 1.判断是否已注册-防止dubbo的循环依赖
//        boolean registered = userService.isRegistered(email);
//        if (registered) {
//            return false;
//        }

        // 2.发送验证码
        String randonCode = CommonUtils.getEmailCode();

        AuthCode authCode = new AuthCode();
        authCode.setEmail(email);
        authCode.setCode(randonCode);
        // 生成过期时间
        long timeMillis = System.currentTimeMillis();
        authCode.setCreateTime(new Timestamp(timeMillis));
        authCode.setExpireTime(new Timestamp(timeMillis + CODE_TIME_OUT));
        codeEmailDao.save(authCode);

        // 邮箱发送服务
        return emailService.sendCode(email, randonCode);
    }

    /**
     * 校验邮箱验证码
     * @param email
     * @param code
     * @return
     */
    @Override
    public int validate(String email, String code) {
        AuthCode emailCode = new AuthCode();
        emailCode.setEmail(email);
        emailCode.setCode(code);

        List<AuthCode> all = codeEmailDao.findAll(Example.of(emailCode), Sort.by(Sort.Order.desc("expireTime")));
        if (CollectionUtils.isEmpty(all)) {
            return ConstantsUtils.STATUS_1;
        }

        AuthCode one = all.get(0);
        // 判断是否超时
        if (isTimeout(one.getExpireTime())) {
            return ConstantsUtils.STATUS_2;
        }
        return ConstantsUtils.STATUS_0;
    }

    /**
     * 判断是否超时
     * @param expireTime
     * @return
     */
    private boolean isTimeout(Timestamp expireTime) {
        if (expireTime == null) {
            return false;
        }
        return System.currentTimeMillis() > expireTime.getTime() ;
    }
}
